package com.ruoyi.web.controller.an;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.an.domain.*;
import com.ruoyi.an.service.IAnMechanismService;
import com.ruoyi.an.service.IAnMechanismSettlementInfoService;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.an.service.IAnMechanismSettlementService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 机构佣金Controller
 *
 * @author liuzheng
 * @date 2022-11-12
 */
@RestController
@RequestMapping("/an/settlement")
public class AnMechanismSettlementController extends BaseController {
    @Autowired
    private IAnMechanismSettlementService anMechanismSettlementService;
    @Autowired
    private IAnMechanismSettlementInfoService anMechanismSettlementInfoService;
    @Autowired
    private IAnMechanismService anMechanismService;

    /**
     * 查询机构推广数据
     */
    @PreAuthorize("@ss.hasPermi('an:settlement:list')")
    @GetMapping("/info/list")
    public TableDataInfo settlementInfoList(AnMechanism anMechanism) {
        startPage();
        anMechanismSettlementService.syncNullUserMechanismSettlementInfos();
        List<AnMechanism> anMechanisms = anMechanismService.selectAnMechanismList(anMechanism);
        List<AnMechanismSettlementInfoGroupDto> resultList = getAnMechanismSettlementInfoGroupDtos(anMechanisms);
        return getDataTable(resultList);
    }

    private List<AnMechanismSettlementInfoGroupDto> getAnMechanismSettlementInfoGroupDtos(List<AnMechanism> anMechanisms) {
        List<Long> mechanismIds = anMechanisms.stream().map(AnMechanism::getMechanismId).distinct().collect(Collectors.toList());
        List<AnMechanismSettlementInfoGroupDto> resultList = new ArrayList<>();
        if (anMechanisms.size() > 0) {
            List<AnMechanismSettlementInfoDto> list = anMechanismSettlementService.selectAnMechanismSettlementInfoList(mechanismIds);
            //按机构分组
            Map<Long, List<AnMechanismSettlementInfoDto>> MechanismMap = list.stream().collect(Collectors.groupingBy(AnMechanismSettlementInfoDto::getMechanismId));
            for (Map.Entry<Long, List<AnMechanismSettlementInfoDto>> MechanismMapEntry : MechanismMap.entrySet()) {
                Long mechanismId = MechanismMapEntry.getKey();
                List<AnMechanismSettlementInfoDto> mechanismList = MechanismMapEntry.getValue();
                String mechanismName = mechanismList.get(0).getMechanismName();
                AnMechanismSettlementInfoGroupDto mechanismSettlementInfoGroupDto = getAnMechanismSettlementInfoGroupDto(mechanismId, mechanismList, mechanismName);
                //按机构成员分组
                Map<Long, List<AnMechanismSettlementInfoDto>> mechanismMemberMap = mechanismList.stream().filter(item -> item.getMechanismMemberId() != null).collect(Collectors.groupingBy(AnMechanismSettlementInfoDto::getMechanismMemberId));
                List<AnMechanismSettlementInfoChildDto> childList = new ArrayList<>();
                for (Map.Entry<Long, List<AnMechanismSettlementInfoDto>> mechanismMemberMapEntry : mechanismMemberMap.entrySet()) {
                    AnMechanismSettlementInfoGroupDto mechanismMemberMapGroupDto = getAnMechanismSettlementInfoGroupDto(mechanismMemberMapEntry.getKey(), mechanismMemberMapEntry.getValue(), mechanismMemberMapEntry.getValue().get(0).getMechanismName());
                    AnMechanismSettlementInfoChildDto childDto = new AnMechanismSettlementInfoChildDto();
                    childDto.setMemberName(mechanismMemberMapEntry.getValue().get(0).getMemberName());
                    childDto.setMechanismMemberId(mechanismMemberMapEntry.getValue().get(0).getMechanismMemberId());
                    childDto.setEffectiveNumber(mechanismMemberMapGroupDto.getEffectiveNumber());
                    childDto.setCompletedNumber(mechanismMemberMapGroupDto.getCompletedNumber());
                    childList.add(childDto);
                }
                mechanismSettlementInfoGroupDto.setChildList(childList);
                resultList.add(mechanismSettlementInfoGroupDto);
            }
        }
        return resultList;
    }

    private static AnMechanismSettlementInfoGroupDto getAnMechanismSettlementInfoGroupDto(Long mechanismId, List<AnMechanismSettlementInfoDto> mechanismList, String mechanismName) {
        /** 有效测评人数 */
        long effectiveNumber = 0;
        /** 完成人数 */
        long completedNumber = 0;
        /** 待结算佣金 */
        BigDecimal notSettlementPrice = BigDecimal.ZERO;
        /** 已结算佣金 */
        BigDecimal doneSettlementPrice = BigDecimal.ZERO;
        /** 总收益 */
        BigDecimal countSettlementPrice = BigDecimal.ZERO;
        //完成人数计算
        completedNumber = mechanismList.stream().map(AnMechanismSettlementInfoDto::getWechatUserId)
                .filter(Objects::nonNull).distinct().count();
        //有效测评集合
        List<AnMechanismSettlementInfoDto> effectiveList = mechanismList.stream().filter(item -> item.getWechatUserId() != null && item.getAge() != null && item.getAge() >= 50).distinct().collect(Collectors.toList());
        //有效测评人数计算
        effectiveNumber = effectiveList.stream().map(AnMechanismSettlementInfoDto::getWechatUserId).distinct().count();
        //待结算佣金
        List<BigDecimal> notSettlementList = effectiveList.stream().filter(item -> item.getSettlementStatus() == 1).map(AnMechanismSettlementInfoDto::getSettlementPrice)
                .filter(Objects::nonNull).collect(Collectors.toList());
        for (BigDecimal bigDecimal : notSettlementList) {
            notSettlementPrice = notSettlementPrice.add(bigDecimal);
        }
        //已结算佣金
        List<BigDecimal> doneSettlementList = effectiveList.stream().filter(item -> item.getSettlementStatus() == 0).map(AnMechanismSettlementInfoDto::getSettlementPrice)
                .filter(Objects::nonNull).collect(Collectors.toList());
        for (BigDecimal bigDecimal : doneSettlementList) {
            doneSettlementPrice = doneSettlementPrice.add(bigDecimal);
        }
        //总收益
        countSettlementPrice = notSettlementPrice.add(doneSettlementPrice);
        AnMechanismSettlementInfoGroupDto mechanismSettlementInfoGroupDto = new AnMechanismSettlementInfoGroupDto();
        mechanismSettlementInfoGroupDto.setMechanismId(mechanismId);
        mechanismSettlementInfoGroupDto.setMechanismName(mechanismName);
        mechanismSettlementInfoGroupDto.setEffectiveNumber(effectiveNumber);
        mechanismSettlementInfoGroupDto.setCompletedNumber(completedNumber);
        mechanismSettlementInfoGroupDto.setNotSettlementPrice(notSettlementPrice);
        mechanismSettlementInfoGroupDto.setDoneSettlementPrice(doneSettlementPrice);
        mechanismSettlementInfoGroupDto.setCountSettlementPrice(countSettlementPrice);
        return mechanismSettlementInfoGroupDto;
    }

    /**
     * 查询机构佣金列表
     */
    @PreAuthorize("@ss.hasPermi('an:settlement:list')")
    @GetMapping("/list")
    public TableDataInfo list(AnMechanismSettlement anMechanismSettlement) {
        startPage();
        List<AnMechanismSettlement> list = anMechanismSettlementService.selectAnMechanismSettlementList(anMechanismSettlement);
        if(anMechanismSettlement.getMechanismId()!=null){
            for (AnMechanismSettlement mechanismSettlement : list) {
                int effectiveNumberCount = anMechanismSettlementService.getEffectiveNumberCount(mechanismSettlement.getMechanismSettlementId());
                BigDecimal settlementPrice = mechanismSettlement.getSettlementPrice();
                double countSettlementPrice = settlementPrice.doubleValue() * effectiveNumberCount;
                mechanismSettlement.setEffectiveNumberCount(effectiveNumberCount);
                mechanismSettlement.setCountSettlementPrice(BigDecimal.valueOf(countSettlementPrice));
            }
        }
        return getDataTable(list);
    }


//    private BigDecimal getCountSettlementPrice(AnMechanismSettlement mechanismSettlement) {
//        AnMechanismSettlementInfo anMechanismSettlementInfo = new AnMechanismSettlementInfo();
//        anMechanismSettlementInfo.setMechanismSettlementId(mechanismSettlement.getMechanismSettlementId());
//        List<AnMechanismSettlementInfo> anMechanismSettlementInfos = anMechanismSettlementInfoService.selectAnMechanismSettlementInfoList(anMechanismSettlementInfo);
//        List<BigDecimal> doneSettlementList = anMechanismSettlementInfos.stream().map(AnMechanismSettlementInfo::getSettlementPrice)
//                .filter(Objects::nonNull).collect(Collectors.toList());
//        BigDecimal countSettlementPrice = BigDecimal.ZERO;
//        for (BigDecimal bigDecimal : doneSettlementList) {
//            countSettlementPrice = countSettlementPrice.add(bigDecimal);
//        }
//        return countSettlementPrice;
//    }

    /**
     * 导出机构佣金列表
     */
    @PreAuthorize("@ss.hasPermi('an:settlement:export')")
    @Log(title = "机构佣金", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, AnMechanism anMechanism) {
        List<AnMechanism> anMechanisms = anMechanismService.selectAnMechanismList(anMechanism);
        List<AnMechanismSettlementInfoGroupDto> resultList = getAnMechanismSettlementInfoGroupDtos(anMechanisms);
        ExcelUtil<AnMechanismSettlementInfoGroupDto> util = new ExcelUtil<>(AnMechanismSettlementInfoGroupDto.class);
        util.exportExcel(response, resultList, "机构佣金数据");
    }

    /**
     * 获取机构佣金详细信息
     */
    @PreAuthorize("@ss.hasPermi('an:settlement:query')")
    @GetMapping(value = "/{mechanismSettlementId}")
    public AjaxResult getInfo(@PathVariable("mechanismSettlementId") Long mechanismSettlementId) {
        return success(anMechanismSettlementService.selectAnMechanismSettlementByMechanismSettlementId(mechanismSettlementId));
    }

    /**
     * 新增机构佣金
     */
    @PreAuthorize("@ss.hasPermi('an:settlement:add')")
    @Log(title = "机构佣金", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody AnMechanismSettlement anMechanismSettlement) throws ParseException {
        if (anMechanismSettlement.getMechanismId() == null) {
            return AjaxResult.error("请选择机构！");
        }
        AnMechanism anMechanism = anMechanismService.selectAnMechanismByMechanismId(anMechanismSettlement.getMechanismId());
        if (anMechanism.getExamineStatus() != 1) {
            return AjaxResult.error("该机构未通过审核，无法添加佣金！");
        }
        anMechanismSettlement.setSettlementStatus(0L);
        int checkSettlement = anMechanismSettlementService.checkSettlement(anMechanismSettlement).size();
        if (checkSettlement > 0) {
            return AjaxResult.error("该时间段已有结算佣金设置，不可添加");
        }
        if (anMechanismSettlement.getEndTime() == null) {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            Date maxDate = format.parse("2099-01-01");
            anMechanismSettlement.setEndTime(maxDate);
        }
        anMechanismSettlement.setCreateBy(getUsername());
        anMechanismSettlement.setCreateTime(DateUtils.getNowDate());
        return toAjax(anMechanismSettlementService.insertAnMechanismSettlement(anMechanismSettlement));
    }

    /**
     * 修改机构佣金
     */
    @PreAuthorize("@ss.hasPermi('an:settlement:edit')")
    @Log(title = "机构佣金", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody AnMechanismSettlement anMechanismSettlement) {
        //批量修改佣金明细的结算状态
        LoginUser loginUser = getLoginUser();
        if (anMechanismSettlement.getSettlementStatus() == 1) {
            AnMechanismSettlementInfo anMechanismSettlementInfo = new AnMechanismSettlementInfo();
            anMechanismSettlementInfo.setMechanismSettlementId(anMechanismSettlement.getMechanismSettlementId());
            anMechanismSettlementInfo.setUpdateBy(loginUser.getUsername());
            anMechanismSettlementInfo.setUpdateTime(DateUtils.getNowDate());
            anMechanismSettlementInfoService.updateAnMechanismSettlementInfoStatus(0, anMechanismSettlement.getMechanismSettlementId(), loginUser.getUsername());
            //保存结算金额
            int effectiveNumberCount = anMechanismSettlementService.getEffectiveNumberCount(anMechanismSettlement.getMechanismSettlementId());
            BigDecimal settlementPrice = anMechanismSettlement.getSettlementPrice();
            double countSettlementPrice = settlementPrice.doubleValue() * effectiveNumberCount;
//            anMechanismSettlement.setCountSettlementPrice(BigDecimal.valueOf(countSettlementPrice));
            anMechanismSettlement.setRecordCountSettlementPrice(BigDecimal.valueOf(countSettlementPrice));
            anMechanismSettlement.setUpdateBy(loginUser.getUsername());
            anMechanismSettlement.setUpdateTime(DateUtils.getNowDate());
            return toAjax(anMechanismSettlementService.updateAnMechanismSettlement(anMechanismSettlement));
        } else {
            return AjaxResult.error("已结算不支持修改！");
        }
    }

    /**
     * 删除机构佣金
     */
    @PreAuthorize("@ss.hasPermi('an:settlement:remove')")
    @Log(title = "机构佣金", businessType = BusinessType.DELETE)
    @DeleteMapping("/{mechanismSettlementIds}")
    public AjaxResult remove(@PathVariable Long[] mechanismSettlementIds) {
        for (Long mechanismSettlementId : mechanismSettlementIds) {
            AnMechanismSettlement anMechanismSettlement = new AnMechanismSettlement();
            anMechanismSettlement.setMechanismSettlementId(mechanismSettlementId);
            List<AnMechanismSettlement> anMechanismSettlements = anMechanismSettlementService.selectAnMechanismSettlementList(anMechanismSettlement);
            long count = anMechanismSettlements.stream().filter(item -> item.getSettlementStatus() == 1).count();
            //已结算的不能删除
            if (count > 0) {
                return AjaxResult.error("该佣金已结算，无法删除！");
            }
        }
        return toAjax(anMechanismSettlementService.deleteAnMechanismSettlementByMechanismSettlementIds(mechanismSettlementIds));
    }
}
